package com.lagou.edu.filter;

import com.lagou.edu.common.RestResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

@Component
public class AuthFilter implements GlobalFilter, Ordered {

    @Autowired
    private RestTemplate restTemplate;

    // 不需要鉴权的url
    private static List<String> urlWhiteList = new ArrayList<>();

    static {
        urlWhiteList.add("/user/register/.*");
        urlWhiteList.add("/user/isRegistered/.*");
        urlWhiteList.add("/user/login/.*");
        urlWhiteList.add("/code/create/.*");
        urlWhiteList.add("/code/validate/.*");
    }

    private boolean noNeedAuth(String url) {
        for (String urlPattern : urlWhiteList) {
            if (Pattern.matches(urlPattern, url)) {
                return true;
            }
        }

        return false;
    }

    private String getEmailFromToken(String token) {
        if (token == null) {
            return null;
        }

        String url = "http://lagou-service-user/user/info/" + token;
        RestResult ret = restTemplate.getForObject(url, RestResult.class);

        if (ret == null) {
            return null;
        } else {
            return (String)ret.getData();
        }
    }

    /**
     * 鉴权过滤器
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();



        if (!noNeedAuth(request.getURI().getPath())) {   // 不是白名单，需要授权
            List<HttpCookie> token = request.getCookies().get("token");

            String email;
            if (token == null || token.isEmpty() || (email = getEmailFromToken(token.get(0).getValue())) == null) {   // 未授权
                response.setStatusCode(HttpStatus.UNAUTHORIZED);
                DataBuffer wrap = response.bufferFactory().wrap("Unauthorized".getBytes(StandardCharsets.UTF_8));
                return response.writeWith(Mono.just(wrap));
            } else if ("/user/info".equals(request.getURI().getPath())) {
                DataBuffer wrap = response.bufferFactory().wrap(email.getBytes(StandardCharsets.UTF_8));
                return response.writeWith(Mono.just(wrap));
            }


        }



        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
